package main.userInterface.panels;


import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.File;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTabbedPane;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import main.demonutils.io.AbstractIOController;
import main.demonutils.io.IOController;
import main.model.island.IslandInterface;
import main.model.island.RandomIsland;
import main.model.island.grid.GridFactory;
import main.model.island.grid.GridType;
import main.userInterface.islandui.IslandFrame;
import main.userInterface.islandui.SquareSample;




@SuppressWarnings("serial")
public class IslandEditorPanel extends JPanel{
    private IslandFrame islandFrame;
    private IslandInterface island;
    private IOController io;
    
    JLabel dirIntroLab = new JLabel("The current directory is:");
    JLabel dirLab;
    JLabel explainLab = new JLabel("This Directory contains the following *.isl files:");
    JList choicesArea;
    JButton chooseDir = new JButton("Choose Directory");
    
    //File loadedDirectory = null;
    File[] dirContent = null;
    File loadedIsland = null;
    boolean editedBoo = false;
    String[] extensions = {"isl"};
    JLabel loadStatus = new JLabel();
    JLabel editStatus = new JLabel();

    JButton saveBut = new JButton("Save Island");
    JButton saveAsBut = new JButton("Save Island As ...");
    JButton loadBut = new JButton("Load Island");
    JButton deleteBut = new JButton("Delete File");
    
    JButton randBut = new JButton("Randomise Island");
    JButton clearBut = new JButton("Clear Island");
    
    JSlider xSlider, ySlider;
    JLabel xLab, yLab;
    JButton applyisland = new JButton("Apply Size");
    
    ButtonGroup group;
    JRadioButton rba, rbg, rbt;
    SquareSample SSa = new SquareSample(0,20);
    SquareSample SSg = new SquareSample(1,20);
    SquareSample SSt = new SquareSample(2,20);
    SquareSample SSh = new SquareSample(3,20);
    
    JSlider healthSlider;
    JLabel healthLab;
    
    int ISLANDMIN = 10;
    int ISLANDMAX = 50;
    int ISLANDINIT = 10;
    
    //boolean CLICK = false;
    private GridType selectedGridType = GridType.SAND;

    int health = 1000;
    
    public IslandEditorPanel(){
        this.setLayout(new BorderLayout());


        island = RandomIsland.createRandomIsland();
        islandFrame = new IslandFrame(island);

        int ISLANDMIN = island.getMinSize();
        int ISLANDMAX = island.getMaxSize();
        int ISLANDINIT = island.getDefaultSize();
        
        //SAVEPAN settings
        JPanel loadsavePan = new JPanel();
        loadsavePan.setLayout(new BoxLayout(loadsavePan,BoxLayout.PAGE_AXIS));
        
        JPanel loadPan = new JPanel(new BorderLayout());
        JPanel loadLabPan = new JPanel(new GridLayout(0,1,0,0));
        loadLabPan.add(dirIntroLab);
        //dirLab = new JLabel(RIO.getFileString(loadedDirectory));
        //loadLabPan.add(dirLab);
        loadLabPan.add(explainLab);
        loadLabPan.setAlignmentX(Component.RIGHT_ALIGNMENT);
        
        JPanel loadChoicesPan = new JPanel();
        loadChoicesPan.setLayout(new BoxLayout(loadChoicesPan,BoxLayout.PAGE_AXIS));
        choicesArea = new JList();
        choicesArea.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        choicesArea.setLayoutOrientation(JList.VERTICAL);
        JScrollPane choicesScroll = new JScrollPane(choicesArea);
        choicesScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        choicesScroll.setAlignmentX(Component.CENTER_ALIGNMENT);
        chooseDir.setAlignmentX(Component.RIGHT_ALIGNMENT);
        loadChoicesPan.add(choicesScroll);
        loadChoicesPan.add(chooseDir);
        
        loadPan.add(loadLabPan, BorderLayout.PAGE_START);
        loadPan.add(loadChoicesPan, BorderLayout.CENTER);
        loadPan.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Loading Options"), BorderFactory.createEmptyBorder(5,5,5,5)), loadPan.getBorder()));
        
        JPanel savePan = new JPanel(new GridLayout(0,1));
        savePan.add(saveBut);
        savePan.add(saveAsBut);
        savePan.add(loadBut);
        savePan.add(deleteBut);
        savePan.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Saving Options"), BorderFactory.createEmptyBorder(5,5,5,5)), savePan.getBorder()));
        
        loadsavePan.add(loadPan);
        loadsavePan.add(savePan);
        
        //PANELS FOR SIZE
        JPanel islandsize = new JPanel();
        islandsize.setLayout(new BoxLayout(islandsize,BoxLayout.PAGE_AXIS));
        
        JPanel islandsizeX = new JPanel();
        xSlider = new JSlider(JSlider.HORIZONTAL,ISLANDMIN,ISLANDMAX,ISLANDINIT);
        xSlider.setMajorTickSpacing(10);
        xSlider.setMinorTickSpacing(5);
        //xSlider.setPaintTicks(true);
        //xSlider.setPaintLabels(true);
        xLab = new JLabel("X: "+xSlider.getValue());
        islandsizeX.add(xSlider);
        islandsizeX.add(xLab);
        
        JPanel islandsizeY = new JPanel();
        ySlider = new JSlider(JSlider.HORIZONTAL,ISLANDMIN,ISLANDMAX,ISLANDINIT);
        ySlider.setMajorTickSpacing(10);
        ySlider.setMinorTickSpacing(5);
        //ySlider.setPaintTicks(true);
        //ySlider.setPaintLabels(true);
        yLab = new JLabel("Y: "+ySlider.getValue());
        islandsizeY.add(ySlider);
        islandsizeY.add(yLab);
        
        islandsize.add(islandsizeX);
        islandsize.add(islandsizeY);
        islandsize.add(applyisland);
        islandsize.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Set HexIsland Size"), BorderFactory.createEmptyBorder(5,5,5,5)), islandsize.getBorder()));

        //TERchoose SETTINGS
        JPanel TERchoose = new JPanel();
        TERchoose.setLayout(new BoxLayout(TERchoose,BoxLayout.PAGE_AXIS));
        rba = new JRadioButton("Sandy terrain");
        rba.setMnemonic(KeyEvent.VK_S);
        rba.setSelected(true);
        rbg = new JRadioButton("Grassy terrain");
        rbg.setMnemonic(KeyEvent.VK_G);
        rbt = new JRadioButton("Tree on grassy terrain");
        rbt.setMnemonic(KeyEvent.VK_T);
        group = new ButtonGroup();
        group.add(rba); group.add(rbg); group.add(rbt);
        JPanel aPan = new JPanel(new FlowLayout(FlowLayout.LEADING));
        aPan.add(SSa); aPan.add(rba);
        JPanel gPan = new JPanel(new FlowLayout(FlowLayout.LEADING));
        gPan.add(SSg); gPan.add(rbg);
        JPanel tPan = new JPanel(new FlowLayout(FlowLayout.LEADING));
        tPan.add(SSt); tPan.add(rbt);
        
        JPanel healthPan = new JPanel(new FlowLayout(FlowLayout.LEADING));
        healthSlider = new JSlider(JSlider.HORIZONTAL,0,1000,1000);
        healthLab = new JLabel();
        JLabel healthDecLab = new JLabel();
        healthDecLab.setText("Tree Health: ");
        healthLab.setText(""+healthSlider.getValue());
        healthSlider.setMajorTickSpacing(200);
        healthSlider.setMinorTickSpacing(50);
        healthSlider.setPaintTicks(true);
        healthSlider.setPaintLabels(true);
        healthPan.add(SSh);
        healthPan.add(healthDecLab);
        healthPan.add(healthLab);
        
        TERchoose.add(aPan);
        TERchoose.add(gPan);
        TERchoose.add(tPan);
        TERchoose.add(healthPan);
        TERchoose.add(healthSlider);
        TERchoose.add(randBut);
        TERchoose.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Terrain Types"), BorderFactory.createEmptyBorder(5,5,5,5)), TERchoose.getBorder()));
        
        JPanel setResetPan = new JPanel(new GridLayout(0,1));
        setResetPan.add(randBut);
        setResetPan.add(clearBut);
        setResetPan.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Set or Reset Terrain"), BorderFactory.createEmptyBorder(5,5,5,5)), setResetPan.getBorder()));
        
        JPanel editPan = new JPanel();
        editPan.setLayout(new BoxLayout(editPan,BoxLayout.PAGE_AXIS));
        editPan.add(setResetPan);
        editPan.add(islandsize);
        editPan.add(TERchoose);
        
        JPanel editParPan = new JPanel(new BorderLayout());
        editParPan.add(editPan, BorderLayout.NORTH);
        editParPan.add(new JPanel(), BorderLayout.CENTER);
        
        JScrollPane saveLoadPanSC = new JScrollPane(loadsavePan);
        saveLoadPanSC.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        saveLoadPanSC.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        JScrollPane editPanSC = new JScrollPane(editParPan);
        editPanSC.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        editPanSC.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        
        JTabbedPane optionsTabPane = new JTabbedPane();
        optionsTabPane.addTab("Load and Save", null, saveLoadPanSC ,"Choices for loading and saving the island.");
        optionsTabPane.addTab("HexIsland Settings", null, editPanSC ,"Options for changing the island.");
        
        JPanel currentStatus = new JPanel();
        currentStatus.setLayout(new BoxLayout(currentStatus,BoxLayout.PAGE_AXIS));
        currentStatus.add(loadStatus);
        currentStatus.add(editStatus);
        currentStatus.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Current HexIsland Status"), BorderFactory.createEmptyBorder(5,5,5,5)), currentStatus.getBorder()));
        
        JPanel sideBar = new JPanel();
        sideBar.setLayout(new BorderLayout());
        sideBar.add(currentStatus, BorderLayout.NORTH);
        sideBar.add(optionsTabPane, BorderLayout.CENTER);
        
        add(islandFrame, BorderLayout.CENTER);
        add(sideBar, BorderLayout.EAST);
        
        setStatus();
        
        /**
         * Mouse listeners to update the 
         */
        /*islandFrame.getIslandCanvas().addMouseListener(new MouseListener(){
            public void mousePressed(MouseEvent e) {
                CLICK = true; //The mouse is currently being held
                //applyMouse(e.getX(),e.getY()); //Apply the ter type to the area under the mouse
                editedBoo = true; //The file is now edited
                //setStatus(); //File is edited, change should be rendered
            }
            public void mouseReleased(MouseEvent e) {CLICK = false;} //The mouse is no longer clicked
            public void mouseEntered(MouseEvent e) {}
            public void mouseExited(MouseEvent e) {}
            public void mouseClicked(MouseEvent e) {}
        });*/
        islandFrame.getIslandCanvas().addMouseMotionListener(new MouseMotionListener(){
            public void mouseDragged(MouseEvent e){
                applyMouse(e.getX(),e.getY()); //If the mouse is clicked, apply the terrain
            }
            public void mouseMoved(MouseEvent e){}
        });

        /**
         * Change listeners for editing the labels to show the new x and y values
         */
        xSlider.addChangeListener(new ChangeListener(){
            public void stateChanged(ChangeEvent e){
                xLab.setText("X: "+xSlider.getValue());
            }
        });
        ySlider.addChangeListener(new ChangeListener(){
            public void stateChanged(ChangeEvent e){
                yLab.setText("Y: "+ySlider.getValue());
            }
        });
        
        /**
         * Change listener for the changes on the tree heath
         */
        healthSlider.addChangeListener(new ChangeListener(){
            public void stateChanged(ChangeEvent e){
                healthLab.setText(""+healthSlider.getValue());
                SSh.setHealth(healthSlider.getValue()); //The tree health for the square
                SSt.setHealth(healthSlider.getValue()); //The tree health for the tree
                health = healthSlider.getValue();
                rbt.setSelected(true); //Select the radio button for trees
            }
        });
        
        applyisland.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent ae){
                islandFrame.getIsland().setSize(xSlider.getValue(),ySlider.getValue());
                editedBoo = true;
                //setStatus();
            }
        });

        ChangeListener myRadioListener = new ChangeListener(){
            public void stateChanged(ChangeEvent e) {
                if(rba.getModel()==group.getSelection()){selectedGridType=GridType.SAND;}
                else if(rbg.getModel()==group.getSelection()){selectedGridType=GridType.GRASS;}
                else if(rbt.getModel()==group.getSelection()){selectedGridType=GridType.TREE;}
            }
        };
        rba.addChangeListener(myRadioListener);
        rbg.addChangeListener(myRadioListener);
        rbt.addChangeListener(myRadioListener);

        randBut.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent ae){
                islandFrame.getIsland().randomize();
                loadedIsland = null;
                editedBoo = false;
                //setStatus();
            }
        });
        
        clearBut.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent ae){
                islandFrame.getIsland().clear();
                loadedIsland = null;
                editedBoo = false;
                //setStatus();
            }
        });
        /*        
        chooseDir.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                File f = RIO.chooseDirectory();
                if(f != null){loadedDirectory = f;}
                updateFileView();
            } 
        });
        
        saveBut.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent ae){
                if(RIO.saveTerrain(TER,loadedIsland)){
                    editedBoo = false;
                }
                setStatus();
            }   
        });
        
        saveAsBut.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent ae){
                File f = RIO.newFileName(loadedDirectory , "ter");
                if(f != null){
                    if(RIO.saveTerrain(TER,f)){
                        editedBoo = false;
                    }
                }
                setStatus();
            }   
        });
        
        loadBut.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent ae){
                if(choicesArea.getSelectedIndex() >= 0 && choicesArea.getSelectedIndex() < dirContent.length){
                    TER = RIO.loadTerrain(dirContent[choicesArea.getSelectedIndex()]);
                    iFrame.setTER(TER);
                    setDIM();
                    xSlider.setValue(xDIM);
                    ySlider.setValue(yDIM);
                    loadedIsland = TER.getLI();
                    editedBoo = false;
                    setStatus();
                }else{
                    JOptionPane.showMessageDialog(null, "No file has been selected to load.");
                }
            }   
        });
        
        deleteBut.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent ae){
                if(choicesArea.getSelectedIndex() >= 0 && choicesArea.getSelectedIndex() < dirContent.length){
                    RIO.deleteFile(dirContent[choicesArea.getSelectedIndex()]);
                    setStatus();
                }else{
                    JOptionPane.showMessageDialog(null, "No file has been selected to delete.");
                    setStatus();
                }
            }   
        });*/
    }
    
    private void applyMouse(int xmouse,int ymouse){
    	int x = islandFrame.getIslandCanvas().getXbyMouse(xmouse);
    	int y = islandFrame.getIslandCanvas().getYbyMouse(ymouse);
    	
    	GridType g = getSelectedGridType();
    	island.setGrid(x, y, GridFactory.newGrid(g));
        islandFrame.repaint();
    }
    
    private GridType getSelectedGridType() {
		return selectedGridType;
	}

	
    
    /**
     * Updates the list of files to display
     */
    public void updateFileView(){
        //dirLab.setText(io.getCurrentDir().getPath());
        //dirContent = io.getDirContent(extensions);
        /*for(int i = 0;i<names.length;i++){
            names[i] = directory[i].getName(); //populate names
        }
        return names;*/
        //choicesArea.setListData(dirContent);
    }

    
    /**
     * Gives a readout of the status of the current file
     */
    private void setStatus(){ 
        if(loadedIsland == null){
            saveBut.setEnabled(false);
            loadStatus.setText("The current HexIsland is a new, unsaved island.");
            if(!editedBoo){editStatus.setText("\nThe island has not been edited.");
            }else{editStatus.setText("\nThe island has been edited.");}
        }else{
            saveBut.setEnabled(true);
            loadStatus.setText("This is island "+loadedIsland.getName()+".");
            if(!editedBoo){editStatus.setText("\nThe island has not been edited.");
            }else{editStatus.setText("\nThe island has been edited but not saved.");}
        }
        updateFileView();
    }
}